package bsserver;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Calendar;

/**
 * Event Logger for BSServer, based on Common Log Format (CLF).
 * @author marc
 */
public class AccessLogger {

    BufferedWriter output;
    SimpleDateFormat dateFormatter =
            new SimpleDateFormat("[dd/MMM/yyyy:HH:mm:ss Z]");
    String fileName;

    /**
     * AccessLog logger.  Instantiaion opens specified access log for appending.
     * @param fileName name of access log to append to.
     */
    public AccessLogger(String fileName) {
        try {
            output = new BufferedWriter(new FileWriter(fileName, true));
            this.fileName = fileName;
        } catch (IOException e) {
            System.out.println("IO Error: access log:");
            e.printStackTrace();
            System.exit(1);
        }
    }

    /**
     * Logs an access.  Should be called immediately after the data has
     * been sent.  Will place time function called into the access file.
     * Logs in common log format (see above).
     * <p>
     * The following information is from:<br />
     * <a href="http://httpd.apache.org/docs/1.3/logs.html#common">
     * http://httpd.apache.org/docs/1.3/logs.html#common</a><br />
     * <a href="http://www.w3.org/Daemon/User/Config/Logging.html#common-logfile-format">
     * http://www.w3.org/Daemon/User/Config/Logging.html#common-logfile-format</a>
     * <p>
     * The common logfile format is as follows:<br />
     * <pre>
     *     remotehost rfc931 authuser [date] "request" status bytes
     *
     * remotehost
     *     Remote hostname (or IP number if DNS hostname is not available,
     *     or if DNSLookup is Off.
     * rfc931
     *     The remote logname of the user.
     * authuser
     *     The username as which the user has authenticated himself.
     * [date]
     *     Date and time of the request.
     * [10/Oct/2000:13:55:36 -0700]
     * The time that the server finished processing the request. The format is:
     *  [day/month/year:hour:minute:second zone]
     *  day = 2*digit
     *  month = 3*letter
     *  year = 4*digit
     *  hour = 2*digit
     *  minute = 2*digit
     *  second = 2*digit
     *  zone = (`+' | `-') 4*digit
     *
     * "request"
     *     The request line exactly as it came from the client.
     * status
     *     The HTTP status code returned to the client.
     * bytes
     *     The content-length of the document transferred.
     *     - if no data returned.
     * </pre>
     * 
     * @param remoteHost the Internet address of the remote host
     * @param URI the requested resource URI from the remote host
     * @param status the status code returned to the remote host
     * @param bytes the number of bytes written to the remote host
     */
    public void logRequest(String remoteHost, String URI,
            String status, Integer bytes) {

        Calendar now = Calendar.getInstance();

        try {

            output.write(remoteHost.trim());
            output.write(" - - ");
            output.write(dateFormatter.format(now.getTime()));
            output.write(" ");
            output.write("\"" + URI.trim() + "\" ");
            output.write(status.trim() + " ");
            output.write(bytes.toString() + "\n");

            output.flush();
        } catch (IOException e) {
            System.out.println("IO error writing to " + fileName);
            e.printStackTrace();
            System.exit(1);
        }


    }
}
